package org.bsscheduler;

import java.io.File;
import java.io.IOException;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 *
 * @author tblackstone
 */
public class UsersDB {

    private static String usersFile = "users.xml";

    private UsersDB() {
    }

    static {
        File f = new File(usersFile);
        System.out.println("Looking for users file in: " + f.getAbsolutePath());
        EventsDB.startup();
    }


    /**
     * Checks if the given username exists in the data file. Returns true if the
     * name is found, false otherwise.
     * @param username the username to search for
     * @return true if a user entry is found with the given username attribute,
     * otherwise false
     */
    public static boolean userExists(String username) {

        File f = new File(usersFile);
        if (!f.exists()) {
            return false;
        }

        try {
            // Create XML document parser
            DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document data = db.parse(f);
            NodeList users = data.getElementsByTagName("user");

            for (int i = 0; i < users.getLength(); i++) {
                Element u = (Element) users.item(i);
                if (username.equals(u.getAttribute("username"))) {
                    return true;
                }
            }



        } catch (SAXException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        }

        return false;
    }


    /**
     * Creates a new user from the given parameters.  This method assumes that
     * the username does not already exist.
     * @param username the new username entry
     * @param password the new user's password
     * @param firstname the new user's first name
     * @param lastname the new user's last name
     */
    public static synchronized void createUser(String username, String password, String firstname,
            String lastname) {

        File f = new File(usersFile);
        Document data;
        DocumentBuilder db;
        try {
            // Create XML document parser
            db = DocumentBuilderFactory.newInstance().newDocumentBuilder();

            if (f.exists()) {
                try {
                    // parse data file
                    data = db.parse(f);
                } catch (SAXException ex) {
                    Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
                    return;
                } catch (IOException ex) {
                    Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
                    return;
                }
            } else {
                // create new data file
                data = db.newDocument();
                Element usersRoot = data.createElement("users");
                data.appendChild(usersRoot);

            }

            // Add new user to document tree
            Element newUser = data.createElement("user");
            newUser.setAttribute("username", username);
            newUser.setAttribute("password", password);
            newUser.setAttribute("first", firstname);
            newUser.setAttribute("last", lastname);
            data.getFirstChild().appendChild(newUser);

            // Write new document tree to file
            Transformer decepticon = TransformerFactory.newInstance().newTransformer();
            decepticon.setOutputProperty(OutputKeys.INDENT, "yes");
            DOMSource source = new DOMSource(data);
            StreamResult result = new StreamResult(f);
            decepticon.transform(source, result);


        } catch (TransformerConfigurationException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TransformerException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        }

    }


    /**
     * Validate the given username/password pair with the data file. Returns
     * true if the username and password match an entry in the data file,
     * otherwise false.  Also sets the User object properties firstname and
     * lastname from the matching entry in the data file.
     * @param login the User object to update if the user is validated
     * @param username the username to check for in the data file
     * @param password the password to check for in the data file
     * @return
     */

    public static boolean checkLogin(User login, String username, String password) {

        File f = new File(usersFile);
        if (!f.exists()) {
            return false;
        }

        try {
            // Create XML document parser
            DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document data = db.parse(f);
            NodeList users = data.getElementsByTagName("user");

            for (int i = 0; i < users.getLength(); i++) {
                Element u = (Element) users.item(i);
                if (username.equals(u.getAttribute("username")) &&
                        password.equals(u.getAttribute("password"))) {
                    login.setLoggedIn(true);
                    login.setEmail(username);
                    login.setFirstName(u.getAttribute("first"));
                    login.setLastName(u.getAttribute("last"));
                    login.loadEvents();
                    UserManager.addUser(login);
                    return true;
                }
            }

            login.logout();
            return false;

        } catch (SAXException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        }

        login.logout();
        return false;

    }

    public static TreeMap<String, String> userList() {
        return (userList(true));
    }

      /**
     * returns a TreeMap of users and email addresses
    * @return TreeMap of users and email addresses
     */
    public static TreeMap<String, String> userList(boolean lastFirst) {

        TreeMap<String, String> outputMap = new TreeMap<String, String>();

        File f = new File(usersFile);
        if (!f.exists()) {
            return outputMap;
        }

        try {
            // Create XML document parser
            DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document data = db.parse(f);
            NodeList users = data.getElementsByTagName("user");

            for (int i = 0; i < users.getLength(); i++) {
                Element u = (Element) users.item(i);
                if (lastFirst) {
                    outputMap.put(u.getAttribute("username"),
                        u.getAttribute("last") + ", " + u.getAttribute("first"));
                } else {
                    outputMap.put(u.getAttribute("username"),
                        u.getAttribute("first") + " " + u.getAttribute("last"));
                }
            }


        } catch (SAXException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(UsersDB.class.getName()).log(Level.SEVERE, null, ex);
        }

        return outputMap;
    }



    public static String getSelectionList(String excludedUser){
        String output = "";

        TreeMap<String,String> myMap = userList();

        for(String s : myMap.keySet()){
            if(!s.equals(excludedUser)) {
                output += "<option value = \""+ s +"\">" + myMap.get(s) + "</option>";
            }
        }

        return output;
    }



}
